// Copyright  2004-2008 Backplane Ltd.
//
// This file is part of Ubiquity formsPlayer
//
// Ubiquity formsPlayer is free software; you can redistribute it and/or modify it
// under the terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3 of the License, or (at your
// option) any later version.
//
// Ubiquity formsPlayer is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
// more details.
//
// You should have received a copy of the GNU General Public License
// along with Ubiquity formsPlayer If not, see <http://www.gnu.org/licenses/>.
//	
//
//   Purpose: Implementation of CEventSink.
//   $Id$


#include "stdafx.h"
#include <new>
#include "XForms.h"
#include "XFormsApp.h"
#include "EventSink.h"
#include "xformselement.h"
#include "XFormsXFormsElement.h"
#include "eventmsg.h"
#include "EventSinkHandler.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

extern CXFormsApp theApp;

///////////////////////////////////////////////////////////////////////////// 
// CEventSink 
// [TODO]
// Could probably have this on the actual XFormFCElement class

STDMETHODIMP CEventSink::Invoke(DISPID dispidMember, REFIID riid, LCID lcid, WORD wFlags,
		DISPPARAMS* pdispparams, VARIANT* pvarResult, EXCEPINFO* pexcepinfo, UINT* puArgErr) 
{
	HRESULT hr = S_OK; 
//#ifndef _DEBUG
//	try {
//#endif
		if(m_bHandleThroughHandleEvent && m_pControl)
		{
			hr = m_pControl->handleEvent(dispidMember,pvarResult,pdispparams); 
			//TODO: if the control is an object, pass the event on.  
			//probably only  do this if the event is left unhandled.
			if(S_FALSE == hr && m_pControl->m_pControl) 
			{
				//S_FALSE should be returned when the event has not been handled
				CComQIPtr<IHTMLObjectElement> pOb;
				pOb = m_pControl->m_pControl;
				if(!pOb)
					//set hr to false if it is not an object control
					hr = S_FALSE;
				else
				{
					hr = pOb->Invoke
					(
						dispidMember
						,riid
						,lcid
						,wFlags
						,pdispparams
						,pvarResult
						,pexcepinfo
						,puArgErr
					);
					if(FAILED(hr))
					{
						
						LPDISPATCH pDisp = 0;
						pOb->get_object(&pDisp);

						hr = pDisp->Invoke
						(
							dispidMember
							,riid
							,lcid
							,wFlags
							,pdispparams
							,pvarResult
							,pexcepinfo
							,puArgErr
						);
						::safeRelease(pDisp);
					}
				}
			}
		}
		else if(m_bHandleThroughHandleEvent && m_pHandler)
		{
			hr = m_pHandler->handleEvent(dispidMember,pvarResult,pdispparams);
		}
		else
		{
			//TODO: scrap all of this stuff, the above fn will take over.
			
			if(dispidMember==0 && m_pEventFunc!=NULL)
			{
				hr = m_pEventFunc(m_vdEventDetails,this);
			}
			else if(m_pFormControl)
			{
				switch (dispidMember) 
				{
	//Cannot capture tab with onKeyPress.
	//				case DISPID_HTMLELEMENTEVENTS_ONKEYDOWN:
	//					hr = S_OK;
	//					break; 


					case DISPID_HTMLELEMENTEVENTS_ONBLUR:
						hr = m_pFormControl->onDOMFocusOut();
						break;

					/*
					* If the user clicks on the control
					*/
					case DISPID_HTMLELEMENTEVENTS_ONFOCUS:
						hr = m_pFormControl->onfocus();
						break;
					case DISPID_HTMLELEMENTEVENTS_ONCLICK:
	//					hr = m_pFormControl->onfocus();
						hr = m_pFormControl->onactivate();
						break;

					/*
					* If the user changes the data
					*/
				
					
					
					case DISPID_HTMLINPUTTEXTELEMENTEVENTS_ONCHANGE:
		//			case DISPID_HTMLSELECTELEMENTEVENTS2_ONCHANGE:
						hr = m_pFormControl->onvaluechanged();
						break;
					

					case DISPID_HTMLELEMENTEVENTS_ONMOUSEOVER:
						//TODO: improve this to work more like tooltips
						//	currently appearing onmouseover, 
						//	should have some delay without mousemove 
						//	events before display.
					//	hr = m_pFormControl->onhint();
						break;

					case DISPID_HTMLELEMENTEVENTS_ONHELP:
						hr = m_pFormControl->onhelp();
						*pvarResult = _variant_t(false);//prevent IE help from appearing.
						break;

					default:
						break;
				}
			}
		}
/*
		}catch(...)
		{
			::AtlTrace("\n!formsPlayer.dll - EventSink Error \n");
			ASSERT(0);
		}
*//*
#ifndef _DEBUG
	}
	catch(std::bad_alloc) {
		if(SUCCEEDED(theApp.FormsManager().RegisterEventLog()))
			theApp.FormsManager().WriteEvent(EVENTLOG_ERROR_TYPE, MSG_MEMEX);
		ASSERT(0);
	}
	catch(...) {
		if(SUCCEEDED(theApp.FormsManager().RegisterEventLog()))
			theApp.FormsManager().WriteEvent(EVENTLOG_ERROR_TYPE, MSG_TOPEX);
		ASSERT(0);
	}
#endif
	*/
	return hr;
}

void CEventSink::SetHandler(IEventSinkHandler * pHandler)
{
	m_pHandler = pHandler;
}

/////////////////////////////////////////////////////////////////////////////
// CEventSink
#ifdef COUNT_EVENTSINKS
	unsigned long CEventSink::esCount;
#endif
